﻿using System;
using System.Text;
using System.Reflection;

namespace mmsquare.dotNet.TestHelper
{
    public static class InitialiserFromInstance
    {
        public static string Create(object o)
        {
            Type t = o.GetType();

            StringBuilder sb = new StringBuilder();

            sb.Append("var o = ");

            SerialiseObject(sb, t, o);

            sb.Append(";");

            return sb.ToString();
        }

        private static void SerialiseObject(StringBuilder sb, Type t, object instance)
        {
            sb.Append("new ");
            sb.Append(t.Name);
            sb.Append(" { ");
            foreach (var property in t.GetProperties())
            {
                AppendPropertyValue(sb, property, instance);
            }
            sb.Remove(sb.Length - 2, 2);
            sb.Append(" }");
        }

        private static void AppendPropertyValue(StringBuilder sb, PropertyInfo property, object instance)
        {
            if (!property.CanWrite) return;

            object value = property.GetValue(instance, null);

            if (value == null) return;

            sb.Append(property.Name);
            sb.Append(" = ");
            OutputPropertyValue(sb, value);
            sb.Append(", ");
        }
        
        private static void OutputPropertyValue(StringBuilder sb, object value)
        {
            Type t = value.GetType();

            if (t.IsPrimitive)
            {
                sb.Append(value.ToString());
                return;
            }

            if (value is string)
            {
                if (string.IsNullOrEmpty((string)value)) { sb.Append("string.Empty"); return; }
                sb.Append("\"" + value.ToString() + "\""); return;
            }

            SerialiseObject(sb, t, value);            
        }
    }
}
